package knowledgebase.service;

import java.util.List;
import knowledgebase.dao.PermissionDAO;
import knowledgebase.model.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 *
 * @author eugene
 */
@Service("PermissionService")
public class PermissionService {

    @Autowired
    private PermissionDAO permissionDAO;
    @Autowired
    private UserService userService;
    Log log = LogFactory.getLog(getClass());

    public void setPermisiions(String[] blocksIds, Boolean read, Boolean write, Boolean remove, String[] userIds, String[] roleIds) {
        for (int i = 0; i < blocksIds.length; i++) {
            DocumentBlock block = new DocumentBlock();
            block.setId(blocksIds[i]);
            if (userIds!=null) setPermissionsForUser(userIds, block, read, write, remove);
            if (roleIds!=null) setPermissionsForRole(roleIds, block, read, write, remove);
        }
    }
    
    private void setPermissionsForUser(String[] userIds, DocumentBlock block, Boolean read, Boolean write, Boolean remove) {
        for (String id : userIds) {
            User user = new User();
            user.setId(new Long(id));
            AccessType accessType = new AccessType(3, "Read block");
            setAccessForUser(accessType, block, user, read);
            accessType = new AccessType(2, "Update block");
            setAccessForUser(accessType, block, user, write);
            accessType = new AccessType(4, "Delete block");
            setAccessForUser(accessType, block, user, remove);
        }
    }

    private void setPermissionsForRole(String[] roleIds, DocumentBlock block, Boolean read, Boolean write, Boolean remove) {
        for (String roleId : roleIds) {
            Role role = new Role();
            role.setId(new Long(roleId));
            AccessType accessType = new AccessType(3, "Read block");
            setAccessForRole(accessType, block, role, read);
            accessType = new AccessType(2, "Update block");
            setAccessForRole(accessType, block, role, write);
            accessType = new AccessType(4, "Delete block");
            setAccessForRole(accessType, block, role, remove);
        }
    }

    private void setAccessForUser(AccessType accessType, DocumentBlock block, User user, Boolean isAccessSet) {
        if (isAccessSet) {
            UserDocumentBlockAccess udba = new UserDocumentBlockAccess(null, block, accessType);
            Long userDocumentBlockAccessId = permissionDAO.saveUserDocumentBlockAccess(udba);
            udba.setId(userDocumentBlockAccessId);
            permissionDAO.saveUserBlockAccess(new UserBlockAccess(null, user, udba));
        } else {
            permissionDAO.removeAccessToBlockForUser(user, block, accessType);
        }
    }

    private void setAccessForRole(AccessType accessType, DocumentBlock block, Role role, Boolean isAccessSet) {
        if (isAccessSet) {
            RoleDocumentBlockAccess rdba = new RoleDocumentBlockAccess(null, block, accessType);
            Long roleDocumentBlockAccessId = permissionDAO.saveRoleDocumentBlockAccess(rdba);
            rdba.setId(roleDocumentBlockAccessId);
            permissionDAO.saveRoleBlockAccess(new RoleBlockAccess(null, role, rdba));
        } else {
            permissionDAO.removeAccessToBlockForRole(role, block, accessType);
        }
    }
    
    public List<RoleGlobalPermission> getAllRowGlobalPermissions() {
        return permissionDAO.getAllRowGlobalPermissions();
    }
    
    public List<AccessType> getGlobalRolePermissions(Role role) {
        return permissionDAO.getGlobalRolePermissions(role);
    }
    
    public void setGlobalPermissionsForRoles(List<SimpleGlobalPermission> list){
        if(list==null || list.isEmpty()) return;
        
        for (SimpleGlobalPermission entry: list){
            setGlobalPermissionsForRole(entry);
        }
    }
    
    public void setGlobalPermissionsForRole(SimpleGlobalPermission roleGlobalPermission){
        if(roleGlobalPermission==null) return;
        
        long roleId = roleGlobalPermission.getRoleId();
        
        AccessType accessType = new AccessType(1, "Create block");
        setGlobalAccessForRole(accessType, roleId, roleGlobalPermission.isCreate());
        accessType = new AccessType(2, "Update block");
        setGlobalAccessForRole(accessType, roleId, roleGlobalPermission.isEdit());
        accessType = new AccessType(3, "Read block");
        setGlobalAccessForRole(accessType, roleId, roleGlobalPermission.isRead());
        accessType = new AccessType(4, "Delete block");
        setGlobalAccessForRole(accessType, roleId, roleGlobalPermission.isRemove());
    }
    
    private void setGlobalAccessForRole(AccessType accessType, long roleId, boolean permissionValue) {
        Role role = new Role();
        role.setId(roleId);
        RoleGlobalPermission rgp = new RoleGlobalPermission();
        rgp.setAccessType(accessType);
        rgp.setRole(role);
        if (permissionValue) {
            permissionDAO.saveRoleGlobalAccess(rgp);
        } else {
            permissionDAO.removeRoleGlobalAccess(rgp);
        }
    }
}
